package com.itheima.homework.demo02;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.*;

/**
 * @Author 王加鑫
 * @Date 2021/5/25 20:20
 * @Version 1.0
 * 2、【编号2106】请编写程序，分别模拟使用TCP协议传输数据的客户端和服务器端，完成文件上传。
 * 客户端获取键盘录入的文件路径，将文件上传给服务器端，服务器端获取到数据后，保存到当前模块目录下，并给出反馈。
 * 其中，上传的文件仅允许jpg格式的图片，保存到服务器端的文件，为防止重名覆盖，可使用32位UUID作为文件名。
 * 在实际生产中，服务器端有可能接收多个客户端的上传请求，所以服务器端可以使用多线程实现，为每个客户端开启一条线程完成上传。
 */
public class ServerDemo02 {
    public static void main(String[] args) throws IOException {

        ServerSocket socket = new ServerSocket(10086);

        //创建线程池对象
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3, //线程池核心线程数
                10, //线程池最大线程数
                60, //临时线程失效值
                TimeUnit.SECONDS, //失效的时间单位
                new ArrayBlockingQueue<>(5), //任务队列
                Executors.defaultThreadFactory(), //创建线程工厂
                new ThreadPoolExecutor.AbortPolicy() //任务的拒绝策略
        );



        while (true){
            //服务器端和客户端建立连接(如果没有建立连接,服务器端会死等)
            Socket accept = socket.accept();
            //开启线程
            Runnable r = () -> {
                try {
                    //创建服务器端网络输入流
                    InputStream is = accept.getInputStream();
                    //创建服务器端本地输出流
                    FileOutputStream fos = new FileOutputStream("day16_网络编程/" + UUID.randomUUID().toString().replaceAll("-","") + ".jpg");
                    byte[] b1 = new byte[1024];
                    int i1;
                    while ((i1 = is.read(b1)) != -1){
                        fos.write(b1,0,i1);
                        fos.flush();
                    }
                    //给客户端返回一个提示
                    OutputStream os = accept.getOutputStream();
                    os.write("上传成功".getBytes());
                    os.flush();
                    accept.shutdownOutput();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //获取线程池中的线程对象执行任务
            };

            pool.submit(r);
        }
    }
}
